#include "linear_linked_list.h"
#include <stdlib.h>
#include <string.h>

/**
 * @brief 链表初始化
 * @return 返回链表头（无数据，指向第一个结点）
 */
LinkedNode_t* LinkedListInit()
{
    LinkedNode_t *head = malloc(sizeof(LinkedNode_t));
    if (!head) {
        return NULL;
    }
    head->next = NULL;
    return head;
}

/**
 * @brief 从链表的head开始插入一个节点
 * @param head 链表头
 * @param data 插入的新节点的数据
 */
LinkedStatus_t LinkedListInsertToHead(LinkedNode_t *head, BrowserData_t *data)
{
    LinkedNode_t *newNode = malloc(sizeof(LinkedNode_t));
    if (!newNode) {
        return LINKED_LIST_FAIL;
    }
    newNode->browserData = *data;
    // 新节点的next指向head的next指向的节点
    newNode->next = head->next;
    // head的next指向新节点
    head->next = newNode;
    return LINKED_LIST_SUCCESS;
}

/**
 * @brief 从链表的尾部开始插入一个节点
 * @param head 链表头
 * @param data 插入的新节点的数据
 */
LinkedStatus_t LinkedListInsertToTail(LinkedNode_t *head, BrowserData_t *data)
{
    LinkedNode_t *tailNode = head;
    // 寻找尾节点
    while (tailNode->next != NULL) {
        tailNode = tailNode->next;
    }
    LinkedNode_t *newNode = malloc(sizeof(LinkedNode_t));
    if (!newNode) {
        return LINKED_LIST_FAIL;
    }

    newNode->browserData = *data;
    newNode->next = NULL;
    tailNode->next = newNode;
    return LINKED_LIST_SUCCESS;
}

/**
 * @brief 通用插入函数
 * @param head 链表头
 * @param index 节点序号（从0开始）
 * @param data 插入的新节点的数据
 * @return @{LinkedStatus_t}
 */
LinkedStatus_t LinkedListInsertCom(LinkedNode_t *head, int index, BrowserData_t *data)
{
    if (index < 0 ) {
        return LINKED_LIST_FAIL;
    }
    LinkedNode_t *indexNode = head;

    // 找到index前的一个节点
    for (int i = 0; i < index; i++) {
        if (indexNode == NULL) {
            return LINKED_LIST_FAIL;
        }
        indexNode = indexNode->next;
    }

    if (indexNode == NULL) {
        return LINKED_LIST_FAIL;
    }

    LinkedNode_t *newNode = malloc(sizeof(LinkedNode_t));
    if (!newNode) {
        return LINKED_LIST_FAIL;
    }
    newNode->browserData = *data;
    newNode->next = indexNode->next;
    indexNode->next = newNode;
    return LINKED_LIST_SUCCESS;
}

/**
 * @brief 按索引查找链表节点
 * @param head 链表头
 * @param index 节点索引（从0开始）
 * @return 返回找到的节点，未找到返回NULL
 */
LinkedNode_t *LinkedListSearchByIndex(LinkedNode_t *head, int index)
{
    if (index < 0 ) {
        return NULL;
    }
    LinkedNode_t *indexNode = head;

    // 找到index前的一个节点
    for (int i = 0; i < index; i++) {
        if (indexNode == NULL) {
            return NULL;
        }
        indexNode = indexNode->next;
    }
    if (indexNode == NULL) {
        return NULL;
    }
    return indexNode->next;
}

static LinkedStatus_t CompareBrowserData(BrowserData_t *node1, BrowserData_t *node2)
{
    // 比较标题
    if (strncmp(node1->title, node2->title, MAX_TITLE_LENGTH) != 0) {
        return LINKED_LIST_FAIL;
    }
    // 比较时间戳
    if (strncmp(node1->timestamp, node2->timestamp, MAX_TIMESTAMP_LENGTH) != 0) {
        return LINKED_LIST_FAIL;
    }
    // 比较URL
    if (strncmp(node1->url, node2->url, MAX_URL_LENGTH) != 0) {
        return LINKED_LIST_FAIL;
    }

    return LINKED_LIST_SUCCESS;
}

/**
 * @brief 按数据内容查找链表节点
 * @param head 链表头
 * @param data 要查找的链表节点的数据
 * @return 查找到的链表节点
 */
LinkedNode_t *LinkedListSearchByData(LinkedNode_t *head, BrowserData_t *data)
{
    LinkedNode_t *indexNode = head;
    while (indexNode != NULL) {
        if (CompareBrowserData(&indexNode->browserData, data) == LINKED_LIST_SUCCESS) {
            return indexNode;
        }
        indexNode = indexNode->next;
    }
    return NULL;
}

/**
 * @brief 按索引删除节点
 * @param head 链表头
 * @param index 节点索引（从0开始）
 * @return @{LinkedStatus_t}
 */
LinkedStatus_t LinkedListDeleteByIndex(LinkedNode_t *head, int index)
{
    // 目标的前一个节点
    LinkedNode_t *prevNode = head;
    // 目标节点
    LinkedNode_t *indexNode = LinkedListSearchByIndex(head, index);
    if (!indexNode) {
        return LINKED_LIST_FAIL;
    }
    // 遍历找到目标的前一个节点
    while (prevNode->next  != indexNode) {
        prevNode = prevNode->next;
    }
    // 切换节点链接
    prevNode->next = indexNode->next;
    // 释放要删除的节点的内存
    free(indexNode);
    return LINKED_LIST_SUCCESS;
}

LinkedStatus_t LinkedListDeleteByData(LinkedNode_t *head, BrowserData_t *data)
{
    // 目标的前一个节点
    LinkedNode_t *prevNode = head;
    // 目标节点
    LinkedNode_t *indexNode = LinkedListSearchByData(head, data);
    if (!indexNode) {
        return LINKED_LIST_FAIL;
    }
    // 遍历找到目标的前一个节点
    while (prevNode->next  != indexNode) {
        prevNode = prevNode->next;
    }
    // 切换节点链接
    prevNode->next = indexNode->next;
    // 释放要删除的节点的内存
    free(indexNode);
    return LINKED_LIST_SUCCESS;
}

/**
 * @brief 销毁链表
 * @param head 链表头
 */
void LinkedListDestroy(LinkedNode_t *head)
{
    LinkedNode_t *temp;
    while (head != NULL) {
        temp = head;
        head = head->next;
        free(temp);
    }
}
